﻿module Sustainalytics.LRTM {

    // service for interacting with Long Running Tasks
    export class LongRunningTaskService implements ILongRunningTaskService {

        // ctor
        constructor(
            private $http: ng.IHttpService,
            private $q: ng.IQService,
            private $rootScope: ng.IScope) {
        }

        //#region POST

        // post
        public post(
            id: string,
            title: string,
            paramJson: string,
            taskType: LongRunningTaskTypeEnum,
            fileName: string,
            mimeType: string,
            files: any[],
            uploadProgressFunc: (number) => void,
            isUpload: boolean,
            isDownload: boolean,
            order: number): LongRunningTaskInstancePost {

            var ctx = this;

            var def = ctx.$q.defer();

            var url = '/lrtmserv/api/v1/task?';

            var postData =
                {
                    id: id,
                    title: title,
                    paramJson: paramJson,
                    taskType: taskType,
                    fileName: fileName,
                    mimeType: mimeType,
                    isUpload: isUpload,
                    isDownload: isDownload,
                    order: order
                };

            var formData: FormData = new FormData();

            // add post data
            formData.append('data', JSON.stringify(postData));

            // add files
            if (isUpload && files && files.length > 0) {

                $.each(files, (index, file) => {
                    formData.append('fileUpload' + index, file);
                });
            }


            // ajax submit with upload if required
            var xhr = new XMLHttpRequest();
            xhr.open('POST', url, true);
            xhr.setRequestHeader('Authorization', 'Bearer ' + ctx.$rootScope['authData']['access_token']);

            // track upload progress
            if (uploadProgressFunc && isUpload) {
                xhr.upload.onprogress = function (e) {
                    if (e.lengthComputable) {
                        var percentComplete = (e.loaded / e.total) * 100;
                        uploadProgressFunc(percentComplete);
                    }
                }
            }

            // track request completion
            xhr.onload = function () {
                if (this.status == 200) {
                    def.resolve(this.response);
                }
                else {
                    def.reject(this.response);
                }
            };

            xhr.send(formData);


            var res = new LongRunningTaskInstancePost(xhr, def.promise);
            return res;
        }

        // run task without upload for current user
        public postTask(
            id: string,
            title: string,
            paramJson: string,
            taskType: LongRunningTaskTypeEnum,
            isDownload: boolean,
            order: number): LongRunningTaskInstancePost {
            var ctx = this;

            // start task
            var res = ctx.post(id, title, paramJson, taskType, null, null, null, null, false, isDownload, order);

            return res;
        }

        // run task with file upload for current user
        public postTaskWithUpload(
            id: string,
            title: string,
            paramJson: string,
            taskType: LongRunningTaskTypeEnum,
            files: any[],
            uploadProgressFunc: (number) => void,
            isDownload: boolean,
            order: number): LongRunningTaskInstancePost {

            var ctx = this;

            // start task + upload
            var res = ctx.post(id, title, paramJson, taskType, null, null, files, uploadProgressFunc, true, isDownload, order);

            return res;
        }

        //#endregion


        //#region GET

        // get
        public get(taskInstanceId: string, overallStatus: boolean, getStatus: boolean, getResult: boolean, deleteOnGetResult: boolean): ng.IHttpPromise<any> {
            var ctx = this;

            var url = '/lrtmserv/api/v1/task?';

            var param = $.param(
                {
                    taskInstanceId: taskInstanceId,
                    overallStatus: overallStatus,
                    getStatus: getStatus,
                    getResult: getResult,
                    deleteOnGetResult: deleteOnGetResult
                });

            var promise = ctx.$http.get(url + param);

            return promise;
        }

        // get overall status for current user
        public getOverallStatus(): ng.IPromise<LongRunningTaskInstanceStatus[]> {
            var ctx = this;

            // get overall status
            var promise = ctx.get(null, true, false, false, false);

            return promise;
        }

        // get status for a specific task instance ID
        public getStatus(taskInstanceId: string): ng.IPromise<LongRunningTaskInstanceStatus> {
            var ctx = this;

            // get status
            var promise = ctx.get(taskInstanceId, false, true, false, false);

            return promise;
        }

        // get task instance result as an object
        public getResultAsObject(taskInstanceId: string, deleteOnGetResult: boolean): ng.IPromise<any> {
            var ctx = this;

            var promise = ctx.get(taskInstanceId, false, false, true, deleteOnGetResult);

            return promise;
        }

        // get task instance result as a download
        public getResultAsDownload(taskInstanceId: string, deleteOnGetResult: boolean): void {
            var ctx = this;

            var url = '/lrtmserv/api/v1/task?';

            // get access token
            var accessToken = ctx.$rootScope['authData']['access_token'];

            var param = $.param(
                {
                    taskInstanceId: taskInstanceId,
                    getResult: true,
                    deleteOnGetResult: deleteOnGetResult,
                    'access_token': accessToken
                });

            url = url + param;

            window.open(url, '_self');
        }

        //#endregion


        //#region DELETE

        // delete
        public deleteTaskInstance(taskInstanceId: string): ng.IHttpPromise<any> {
            var ctx = this;

            var url = '/lrtmserv/api/v1/task/' + taskInstanceId;

            var promise = ctx.$http['delete'](url);

            return promise;
        }

        //#endregion
    }


    // register service
    angular.module('Sustainalytics.LRTM').factory('LongRunningTaskService', ($http: ng.IHttpService, $q: ng.IQService, $rootScope: ng.IScope) => {
        var service = new LongRunningTaskService($http, $q, $rootScope);
        return service;
    });
}